import os
import threading
import time
from typing import Dict

from pydantic import BaseModel
import yaml

from common import logger


class Env(BaseModel):
    host: str
    port: int
    title: str


class Amqp(BaseModel):
    name: str
    host: str
    user_name: str
    password: str
    virtual_host: str
    exchange: str
    routing_key: str
    queue: str


class Es(BaseModel):
    host: str
    user: str
    password: str
    port: int


class MongoDb(BaseModel):
    name: str
    ip: str
    port: int
    db_name: str
    maxIdleTimeMS: int
    password: str
    user: str


class Redis(BaseModel):
    name: str
    host: str
    password: str
    port: int
    timeout: int
    prefix: str


class Mysql(BaseModel):
    class _Link(BaseModel):
        name: str
        db_name: str
        user: str
        password: str
        port: int
        host: str

        def get_database_url(self):
            database_url = "mysql://"
            database_url += self.user + ":" + self.password
            database_url += "@" + self.host + ":" + str(self.port)
            database_url += "/" + self.db_name + "?charset=utf8mb4"

            return database_url

    pool_size: int = 20
    pool_recycle: int = 3600
    pool_timeout: int = 15
    max_overflow: int = 2
    connect_timeout: int = 60
    link: Dict[str, _Link]


class Tencent(BaseModel):
    key: str


class Config:
    JdkHome: str
    BASE_DIR: str
    StaticDIR: str
    env: dict[str, Env] = {}
    mongo_db: MongoDb
    redis: Redis
    mysql: Mysql
    tencent: Tencent
    amqp: Amqp
    es: Es

    _instance_lock = threading.Lock()

    @classmethod
    def instance(cls):
        with Config._instance_lock:
            if not hasattr(Config, "_instance"):
                Config._instance = Config()
        return Config._instance

    def __init__(self):
        self.load_config_params()

    def load_config_params(self):
        with open(os.path.join(os.path.dirname(__file__), "conf.dev.yaml"), encoding="utf8") as file:
            dict_value = yaml.load(file.read(), Loader=yaml.FullLoader)
        self.BASE_DIR = os.path.dirname(os.path.dirname(__file__))
        self.StaticDIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "static")

        self.JdkHome = dict_value.get("env", {}).get("jdk_home")
        for server_name, server_name_env in dict_value.get("env", {}).get("ServerMap", {}).items():
            self.env[server_name] = Env(**server_name_env)
        self.mongo_db = MongoDb(**dict_value.get("mongo_db"))
        self.redis = Redis(**dict_value.get("redis"))
        self.mysql = Mysql(**dict_value.get("mysql", {}))
        self.tencent = Tencent(**dict_value.get("tencent"))
        self.amqp = Amqp(**dict_value.get("amqp"))
        self.es = Es(**dict_value.get("elasticsearch"))

        print("""
         █████╗   ██████╗   ███╗   ███╗  ██╗  ███╗   ██╗
        ██╔══██╗  ██╔══██╗  ████╗ ████║  ██║  ████╗  ██║
        ███████║  ██║  ██║  ██╔████╔██║  ██║  ██╔██╗ ██║
        ██╔══██║  ██║  ██║  ██║╚██╔╝██║  ██║  ██║╚██╗██║
        ██║  ██║  ██████╔╝  ██║ ╚═╝ ██║  ██║  ██║ ╚████║ ██╗
        ╚═╝  ╚═╝  ╚═════╝   ╚═╝     ╚═╝  ╚═╝  ╚═╝  ╚═══╝ ╚═╝
        """)

        logger.success("[Config] 加载配置文件成功")

        self.load_jar_home(dict_value.get("Jar") or [])

    def load_jar_home(self, jar_homes):
        for jar_home in jar_homes:
            if not jar_home.endswith('.jar'):
                continue
            jar_file_path = os.path.join(self.BASE_DIR, jar_home)
            os.environ['CLASSPATH'] = os.environ.get('CLASSPATH', '') + ':' + jar_file_path
            logger.success(f"[Jar] 加载{jar_home}成功")


Config = Config.instance()
